package com.zx.tfw.web;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zx.tfw.dao.TechnicalManufacturerDao;
import com.zx.tfw.entity.ResponseData;
import com.zx.tfw.entity.TechnicalFramework;
import com.zx.tfw.entity.TechnicalManufacturer;
import com.zx.tfw.entity.TfwStatisticsModel;
import com.zx.tfw.enums.CountryEnum;
import com.zx.tfw.enums.ForumEnum;
import com.zx.tfw.enums.LanguageEnum;
import com.zx.tfw.enums.LicenseEnum;
import com.zx.tfw.enums.OSEnum;
import com.zx.tfw.enums.PopularEnum;
import com.zx.tfw.enums.SkilledEnum;
import com.zx.tfw.enums.TagEnum;
import com.zx.tfw.enums.TypeEnum;
import com.zx.tfw.service.TechnicalFrameworkService;

@Controller
//@RequestMapping("/tfw")
public class TechnicalFrameworkController {
	
	private final static Logger LOGGER = LoggerFactory.getLogger(TechnicalFrameworkController.class);
	
	@Autowired
	private TechnicalManufacturerDao technicalManufacturerDao;

	@Autowired
	private TechnicalFrameworkService technicalFrameworkService;
	
	/**
	 * @title 初始化页面
	 * @param model
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月28日下午7:45:12
	 */
	@RequestMapping("/index")
	public String index(Model model) {
		model.addAttribute("allTfw", this.technicalFrameworkService.findAll());
		this.setEnums(model);
		return "index";
	}
	
	/**
	 * @title 初始化统一页面
	 * @param model
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月31日下午2:31:24
	 */
	@RequestMapping("/table/html")
	public String table(Model model) {
		model.addAttribute("allTfw", this.technicalFrameworkService.findAll());
		model.addAttribute("allTfw2", this.technicalFrameworkService.classificationByType());
		this.setEnums(model);
		return "table";
	}
	
	/**
	 * @title 新增框架页面
	 * @param model
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月29日下午4:46:22
	 */
	@RequestMapping("/add/html")
	public String addHtml(Model model) {
		this.setEnums(model);
		return "save";
	}
	
	/**
	 * @title 修改框架页面
	 * @param model
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月29日下午4:46:22
	 */
	@RequestMapping("/update/html")
	public String updateHtml(Model model, Integer id) {
		if(id == null) {
			return "404";
		}
		// 详细信息
		model.addAttribute("tfw", this.technicalFrameworkService.findById(id));
		this.setEnums(model);
		return "save";
	}
	
	/**
	 * @title 新增/修改框架
	 * @param tfw
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月29日下午4:46:33
	 */
	@RequestMapping("/save/tfw")
	@ResponseBody
	public ResponseData saveTFW(TechnicalFramework tfw) {
		try {
			LOGGER.info("插入框架信息={}",JSONObject.toJSONString(tfw));
			
			// 初始化是否开源默认值，关闭开关的时候选择的是 够
			tfw.setOpenSources(tfw.getOpenSources() == null ? 0 : tfw.getOpenSources());
			
			if(tfw.getId() == null) {// 新增
				tfw.setCreateTime(new Date());
			} else {//修改
				// TODO 
			}
			// 保存信息
			this.technicalFrameworkService.save(tfw);
			
			return ResponseData.success(null);
		} catch (Exception e) {
			LOGGER.error("插入框架信息出现异常=" + JSONObject.toJSONString(tfw), e);
			return ResponseData.failed(null);
		}
	}
	
	/**
	 * @title 查询某个框架的信息
	 * @param id
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月31日下午2:31:43
	 */
	@RequestMapping("/info/{id}")
	@ResponseBody
	public ResponseData info(@PathVariable("id") Integer id) {
		try {
			if(id == null) {
				return ResponseData.failed(null);
			}
			
			return ResponseData.success(this.technicalFrameworkService.findDtoById(id));
		} catch (Exception e) {
			LOGGER.error("查询异常", e);
			return ResponseData.failed(null);
		}
	}

	/**
	 * @title 获得分类后的数据
	 * @param type
	 * @return
	 * @author: xue.zhang
	 * @date 2019年1月31日下午4:03:05
	 */
	@RequestMapping("/classification")
	@ResponseBody
	public ResponseData classification(Integer type) {
		try {
			if(type == null) {
				return ResponseData.failed(null);
			}
			List<?> data = null;
			String title = null;
			if(type == 1) {// 分类依据--技术类型(用于生成table)
				data = this.technicalFrameworkService.classificationByType();
			} else if(type == 2) {// 分类依据--厂商(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getManufacturerCode, 
						code -> this.technicalManufacturerDao.findById(code).orElse(new TechnicalManufacturer()),
						this.technicalManufacturerDao.findAll()//生成模板数据
							.stream()
							.map(tmf -> new TfwStatisticsModel<TechnicalManufacturer, TechnicalFramework>(tmf, Lists.newArrayList()))
							.collect(Collectors.toList())
						);
				title = "厂商/软件分布情况";
			} else if(type == 3) {// 分类依据--国家(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getCountryCode, 
						code -> CountryEnum.asMap().containsKey(code) ? CountryEnum.asMap().get(code).getName() : "");
				title = "国家/软件分布情况";
			} else if(type == 4) {// 分类依据--熟练度(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getSkilledCode, 
						code -> SkilledEnum.asMap().containsKey(code) ? SkilledEnum.asMap().get(code).getName() + "_" + code + "级": "");
				title = "熟练度/软件分布情况";
			} else if(type == 5) {// 分类依据--语言(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getLanguageCode, 
						code -> LanguageEnum.asMap().containsKey(code) ? LanguageEnum.asMap().get(code).getName() : "");
				title = "语言/软件分布情况";
			} else if(type == 6) {// 分类依据--操作系统(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getOsCode, 
						code -> OSEnum.asMap().containsKey(code) ? OSEnum.asMap().get(code).getName() : "");
				title = "操作系统/软件分布情况";
			} else if(type == 7) {// 分类依据--开源(用于数据分析)
				data = this.technicalFrameworkService.handler(
						TechnicalFramework::getOpenSources, 
						code -> code == 1 ? "开源" : "闭源");
				title = "开源/软件分布情况";
			} 
			return ResponseData.build(200, title, data);
		} catch (Exception e) {
			LOGGER.error("查询异常", e);
			return ResponseData.failed(null);
		}
	}
	
	//########################## 内部私有方法 ##################################//
	/**
	 * @Title: 存入全部基本信息
	 * @param model
	 * @date: 2019年1月29日下午11:15:54
	 * @author: zhangxue
	 */
	private void setEnums(Model model) {
		model.addAttribute("allTmf", this.technicalManufacturerDao.findAll());
		model.addAttribute("language", 		LanguageEnum.values());
		model.addAttribute("os", 			OSEnum.values());
		model.addAttribute("license", 		LicenseEnum.values());
		model.addAttribute("tags", 			TagEnum.values());
		model.addAttribute("country", 		CountryEnum.values());
		model.addAttribute("skilled", 		SkilledEnum.values());
		model.addAttribute("popular", 		PopularEnum.values());
		model.addAttribute("forum", 		ForumEnum.values());
		model.addAttribute("type", 			TypeEnum.values());
	}
}
